package com.cosin.util;

import com.cosin.model.dto.NodeDTO;
import com.cosin.model.po.NodePO;
import com.cosin.model.po.RelationPO;
import com.cosin.service.GraphService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import com.fasterxml.jackson.core.type.TypeReference;

import static java.sql.Types.BOOLEAN;
import static java.sql.Types.NUMERIC;
import static org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType.FORMULA;
import static org.apache.xmlbeans.impl.piccolo.xml.Piccolo.STRING;


@Slf4j
@Service
public class ReadExcel {

    private static final DataFormatter dataFormatter = new DataFormatter();

    private static GraphService graphService;

    @Autowired
    ReadExcel (GraphService graphService){
        ReadExcel.graphService = graphService;
    }



    /**
     * 读取文件
     * @param
     */
    public static List<NodePO> readExcelFile(InputStream inputStream,int projectId) throws IOException {
        List<NodePO> nodePOList = new ArrayList<>();
        try (Workbook workbook = new XSSFWorkbook(inputStream)) {
            // 处理企业工作表
//            Sheet enterpriseSheet = workbook.getSheet("企业");
//            if (enterpriseSheet != null) {
//                nodePOList.addAll(processSheet(enterpriseSheet, "企业",projectId));
//            }
            // 处理发动机表
            Sheet motorSheet = workbook.getSheet("发动机");
            if (motorSheet != null) {
                log.info("读取到发动机表");
                nodePOList.addAll(processSheet(motorSheet, "发动机",projectId));
            }
            // 处理飞机表
            Sheet planeSheet = workbook.getSheet("飞机");
            if (planeSheet != null) {
                log.info("读取到飞机表");
                nodePOList.addAll(processSheet(planeSheet, "飞机",projectId));
            }

//            // 处理专利工作表
//            Sheet patentSheet = workbook.getSheet("专利");
//            if (patentSheet != null) {
//                nodePOList.addAll(processSheet(patentSheet, "专利",projectId));
//            }
//
//            // 处理产品工作表
//            Sheet productSheet = workbook.getSheet("产品");
//            if (productSheet != null) {
//                nodePOList.addAll(processSheet(productSheet, "产品",projectId));
//            }
        }
        return nodePOList;
    }

    // 处理每个工作表的数据
    // 将数据转换成节点信息
    private static List<NodePO> processSheet(Sheet sheet, String group,int projectId) {
        List<NodePO> nodePOList = new ArrayList<>();
        Row headerRow = sheet.getRow(0);
        int columnCount = headerRow.getLastCellNum();

        for (int i = 1; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            // 添加生产厂家节点
            NodePO nodePO1 = new NodePO();
            Map<String, String> properties1 = new HashMap<>();

            // 添加产品节点
            NodePO nodePO2 = new NodePO();
            Map<String, String> properties2 = new HashMap<>();
            int j;
            if (group.equals("飞机")) {
                j = 1;
            } else {
                j = 0;
            }
            for (; j < columnCount; j++) {
                nodePO1.setGroup("公司");
                nodePO1.setRadius(1);
                nodePO1.setProjectId(projectId);
                nodePO1.setColor("");
                nodePO1.setTextSize("15");
                nodePO1.setFigure("");
                Cell cell = row.getCell(j);
                String headerValue = getCellValueAsString(headerRow.getCell(j));
                String cellValue = getCellValueAsString(cell);
                // 如果是名称则设置到节点中, 其他属性则设置到节点属性中
                // 如果属性名称或者属性值为空 则不填入
                if ("生产厂家".equals(headerValue)) {
                    nodePO1.setName(cellValue);
                } else if (!headerValue.isEmpty() && !cellValue.isEmpty() && !"产品名称".equals(headerValue) ) {
                    properties1.put(headerValue, cellValue);
                }
                else if ("产品名称".equals(headerValue)){
                    // 如果遍历到“产品名称”一列 退出循环 再次添加新节点
                    break;
                }
            }
            // 添加产品节点
            for (; j < columnCount; j++) {
                nodePO2.setGroup("产品");
                nodePO2.setRadius(1);
                nodePO2.setProjectId(projectId);
                nodePO2.setColor("");
                nodePO2.setTextSize("15");
                nodePO2.setFigure("");
                Cell cell = row.getCell(j);
                String headerValue = getCellValueAsString(headerRow.getCell(j));
                String cellValue = getCellValueAsString(cell);
                if ("产品名称".equals(headerValue)) {
                    nodePO2.setName(cellValue);
                } else if (!headerValue.isEmpty() && !cellValue.isEmpty()) {
                    properties2.put(headerValue, cellValue);
                }
            }
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 添加厂家属性
                nodePO1.setPropertiesAsString(objectMapper.writeValueAsString(properties1));
                // 添加产品
                nodePO2.setPropertiesAsString(objectMapper.writeValueAsString(properties2));
            } catch (Exception e) {
                log.info("JSON 转换失败: " + e.getMessage());
            }
            // 如果 必要的 名称 不为空 进入列表
            if(!nodePO1.getName().isEmpty()){
                nodePOList.add(nodePO1);
            }
            if(!nodePO2.getName().isEmpty()){
                nodePOList.add(nodePO2);
            }

        }
        // 对公司节点进行去重
        nodePOList = deduplicateCompanies(nodePOList);
        return nodePOList;
    }

    /**
     * 对节点列表进行去重，主要针对公司节点
     * @param nodePOList 待去重的节点列表
     * @return 去重后的节点列表
     */
    private static List<NodePO> deduplicateCompanies(List<NodePO> nodePOList) {
        // 用于存储已存在的公司节点（根据名称和属性判断重复）
        Map<String, NodePO> uniqueCompanies = new HashMap<>();
        // 存储最终结果的列表
        List<NodePO> resultList = new ArrayList<>();

        for (NodePO node : nodePOList) {
            if ("公司".equals(node.getGroup())) {
                try {
                    // 生成公司节点的唯一标识（名称+属性）
                    String companyKey = generateCompanyKey(node);

                    // 如果该公司不存在，则添加到结果列表和已存在公司Map中
                    if (!uniqueCompanies.containsKey(companyKey)) {
                        uniqueCompanies.put(companyKey, node);
                        resultList.add(node);
                    }
                } catch (Exception e) {
                    // 如果处理失败，默认保留该节点
                    log.info("公司节点去重失败: " + e.getMessage());
                    resultList.add(node);
                }
            } else {
                // 非公司节点直接添加到结果列表
                resultList.add(node);
            }
        }

        return resultList;
    }

    /**
     * 生成公司节点的唯一标识（名称+属性）
     * @param companyNode 公司节点
     * @return 唯一标识字符串
     */
    private static String generateCompanyKey(NodePO companyNode) throws JsonProcessingException {
        // 获取公司名称
        String name = companyNode.getName() != null ? companyNode.getName() : "";

        // 获取公司属性并排序
        Map<String, String> properties = new ObjectMapper().readValue(
                companyNode.getPropertiesAsString(),
                new TypeReference<Map<String, String>>() {}
        );

        // 对属性进行排序，确保属性顺序不影响唯一性判断
        TreeMap<String, String> sortedProperties = new TreeMap<>(properties);

        // 生成唯一键（名称+排序后的属性JSON）
        return name + "_" + new ObjectMapper().writeValueAsString(sortedProperties);
    }
    // 处理产品工作表 从产品工作表中读取出节点关系信息
    public static List<RelationPO> extractRelationsFromExcel(InputStream inputStream, int projectId,List<NodePO> nodePOList) throws IOException {
        List<RelationPO> relationPOList = new ArrayList<>();
        try (Workbook workbook = new XSSFWorkbook(inputStream)) {
            Sheet productSheet1 = workbook.getSheet("发动机");
            Sheet productSheet2 = workbook.getSheet("飞机");
            if (productSheet1 != null) {
                relationPOList.addAll(processProductSheet(productSheet1, projectId,nodePOList,  "发动机"));
            }
            if (productSheet2 != null) {
                relationPOList.addAll(processProductSheet(productSheet2, projectId,nodePOList,"飞机"));
            }
        }
        return relationPOList;
    }
    private static List<RelationPO> processProductSheet(Sheet sheet, int projectId, List<NodePO> nodePOList, String group) {
        // 将nodePOList 转换为两个 Map 方便后续查找
        Map<String, Long> companyMap = new HashMap<>();
        Map<String, Long> productMap = new HashMap<>();

        ObjectMapper mapper = new ObjectMapper();

        for (NodePO node : nodePOList) {
            if ("公司".equals(node.getGroup())) {
                companyMap.put(node.getName(), node.getNodeId());
            } else if ("产品".equals(node.getGroup())) {
                try {
                    JsonNode json = mapper.readTree(node.getPropertiesAsString());
                    String model = json.get("型号").asText();
                    productMap.put(model, node.getNodeId());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        List<RelationPO> relationPOList = new ArrayList<>();
        Row headerRow = sheet.getRow(0);
        int columnCount = headerRow.getLastCellNum(); // 获取总列数
        int rowCount = sheet.getLastRowNum(); // 获取总行数
        int nameColumnIndex = -1; // 生产厂家下标
        int modelColumnIndex = -1; // 产品型号下标
        // 根据标头获取相应列的下标
        for (int i = 0; i <= columnCount; i++) {
            if("生产厂家".equals(getCellValueAsString(headerRow.getCell(i)))){
                nameColumnIndex = i;
            } else if("型号".equals(getCellValueAsString(headerRow.getCell(i)))){
                modelColumnIndex = i;
            }
        }

        // 创建 产品 与 公司 的生产关系
        for(int i = 1; i <= rowCount; i++){
            Row row = sheet.getRow(i);
            // 行中的产品型号不为空
            String productModel = getCellValueAsString(row.getCell(modelColumnIndex));
            if(!"".equals(productModel)){
                // 找到公司名称，如果不为空，则创建关系
                    String companyName = getCellValueAsString(row.getCell(nameColumnIndex));
                    // 如果公司名称不为空，则获取公司节点的nodeId，并确定为source
                    if(!companyName.isEmpty()){
                        // 得到公司相应的nodeId
                        long source = companyMap.get(companyName);
                        // 得到产品相应的nodeId
                        long target = productMap.get(productModel);
                        // 填充节点信息
                        RelationPO relationPO = new RelationPO();
                        relationPO.setSource(source);
                        relationPO.setTarget(target);
                        relationPO.setName("生产");
                        relationPO.setWidth(1);
                        relationPO.setProjectId(projectId);
                        relationPOList.add(relationPO);
                    }
            }
        }
        // 创建公司与公司之间的供应关系
        if (group.equals("飞机")) {
            String companyNameMain;
            String companyNameSupply;
            long source = 0;
            long target = 0;
            for(int i = 1; i <= rowCount; i++){
                Row row = sheet.getRow(i);
                // 得到公司的层级，是主要还是供应
                String level = getCellValueAsString(row.getCell(0));
                if ("主要".equals(level)) {
                    companyNameMain = getCellValueAsString(row.getCell(nameColumnIndex));
                    target = companyMap.get(companyNameMain);
                }
                if ("供应".equals(level)) {
                    companyNameSupply = getCellValueAsString(row.getCell(nameColumnIndex));
                    source = companyMap.get(companyNameSupply);
                    RelationPO relationPO = new RelationPO();
                    relationPO.setSource(source);
                    relationPO.setTarget(target);
                    relationPO.setName("供应");
                    relationPO.setWidth(1);
                    relationPO.setProjectId(projectId);
                    relationPOList.add(relationPO);
                }
            }
        }
        return relationPOList;
    }
//    private static List<RelationPO> processProductSheet(Sheet sheet, int projectId) {
//        List<RelationPO> relationPOList = new ArrayList<>();
//        Row headerRow = sheet.getRow(0);
//        int columnCount = headerRow.getLastCellNum(); // 获取总列数
//        int rowCount = sheet.getLastRowNum(); // 获取总行数
//        int nameColumnIndex = -1; // 产品名称下标
//        int modelColumnIndex = -1; // 产品型号下标
//        List<Integer> companyNameIndex = new ArrayList<>();// 公司名称下标
//        List<Integer> patentNumIndex = new ArrayList<>();// 专利号下标
//        // 根据标头获取相应列的下标
//        for (int i = 0; i <= columnCount; i++) {
//            if("产品名称".equals(getCellValueAsString(headerRow.getCell(i)))){
//                nameColumnIndex = i;
//            } else if("产品型号".equals(getCellValueAsString(headerRow.getCell(i)))){
//                modelColumnIndex = i;
//            } else if ("所属单位".equals(getCellValueAsString(headerRow.getCell(i)))) {
//                companyNameIndex.add(i);
//            } else if ("专利号".equals(getCellValueAsString(headerRow.getCell(i)))) {
//                patentNumIndex.add(i);
//            }
//        }
//        // 创建 产品 与 公司 的生产关系
//        for(int i = 1; i <= rowCount; i++){
//            Row row = sheet.getRow(i);
//            // 行中的产品型号不为空
//            String productModel = getCellValueAsString(row.getCell(modelColumnIndex));
//            if(!"".equals(productModel)){
//                // 遍历行中的公司名称，如果不为空，则创建关系
//                for(int j : companyNameIndex){
//                    String companyName = getCellValueAsString(row.getCell(j));
//                    // 如果公司名称不为空，则获取公司节点的nodeId，并确定为source
//                    if(!"".equals(companyName)){
//                        // 得到公司相应的nodeId
//                        long source = graphService.getNodeIdByCompanyNameAndProjectId(companyName,projectId);
//                        // 得到产品相应的nodeId
//                        long target = graphService.getNodeIdByProductModelAndProjectId(productModel, projectId);
//                        // 填充节点信息
//                        RelationPO relationPO = new RelationPO();
//                        relationPO.setSource(source);
//                        relationPO.setTarget(target);
//                        relationPO.setName("生产");
//                        relationPO.setWidth(1);
//                        relationPO.setProjectId(projectId);
//                        relationPOList.add(relationPO);
//                    }
//                }
//                // 创建 产品 与 专利 的关联关系
//                for (int j : patentNumIndex) {
//                    String patentNum = getCellValueAsString(row.getCell(j));
//                    if (!"".equals(patentNum)) {
//                        // 得到产品的nodeId
//                        long source = graphService.getNodeIdByProductModelAndProjectId(productModel, projectId);
//                        // 得到专利的nodeId
//                        long target = graphService.getNodeIdByPatentModelAndProjectId(patentNum, projectId);
//                        // 填充节点信息
//                        RelationPO relationPO = new RelationPO();
//                        relationPO.setSource(source);
//                        relationPO.setTarget(target);
//                        relationPO.setName("引用");
//                        relationPO.setWidth(1);
//                        relationPO.setProjectId(projectId);
//                        relationPOList.add(relationPO);
//                    }
//                }
//            }
//        }
//        return relationPOList;
//    }
    // 读取单元格值并转换为字符串
    private static String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        // 去除字符串前后的空格
        return dataFormatter.formatCellValue(cell).trim();
    }
}
